use salvo::{Depot, FlowCtrl, handler, Request, Response};
use salvo::http::header::CONTENT_TYPE;
use salvo::http::{HeaderValue, ResBody};

#[handler]
pub async fn charset_hoop(req: &mut Request, depot: &mut Depot, res: &mut Response, ctrl: &mut FlowCtrl) {
    ctrl.call_next(req, depot, res).await;
    let header = res.headers_mut();
    match header.get_mut(CONTENT_TYPE) {
        Some(v) => {
            if let Ok(v) = v.to_str() {
                if !v.contains("charset") {
                    let new_content_type = format!("{v}; charset=utf-8");
                    header.insert(CONTENT_TYPE, HeaderValue::from_str(new_content_type.as_str()).unwrap());
                }
            }
        }
        None => {
            header.insert(CONTENT_TYPE, HeaderValue::from_str("text/plain; charset=utf-8").unwrap());
        }
    }
}

#[handler]
pub async fn modify_response_body_hoop(req: &mut Request, depot: &mut Depot, res: &mut Response, ctrl: &mut FlowCtrl) {
    ctrl.call_next(req, depot, res).await;
    match res.body_mut() {
        ResBody::Once(bytes) => {
            let body_str = String::from_utf8(bytes.to_vec()).unwrap();
            let body_str = format!("{body_str}---修改后新增加的响应内容");
            res.replace_body(ResBody::from(body_str));
        }
        _ => {}
    }
}

#[cfg(test)]
mod tests {
    use salvo::Service;
    use salvo::test::{ResponseExt, TestClient};
    use tokio::test;
    use crate::router;

    #[test]
    async fn test_modify_response_body_hoop() {
        let service = Service::new(router());
        let content = TestClient::get(format!("http://127.0.0.1:14300/test_hoop"))
            .send(&service).await.take_string().await.unwrap();
        assert_eq!("原始响应体---修改后新增加的响应内容", content);
    }
}